package mrusanov.ui.battle

import javax.swing.{JPanel, JComponent}
import mrusanov.terrain.TerrainType
import mrusanov.images.{ImageInfo, Image, ImageCache}
import mrusanov.battle.{PlayerState, MiniArena}
import java.awt.{Dimension, Point, Graphics2D, Graphics}
import mrusanov.view.PlayerSprite
import mrusanov.player.PlayerTypeInfoLoader
import mrusanov.team.Team
import mrusanov.sounds.SpriteSoundConfigurationLoader

class MiniArenaComponent(val miniArena:MiniArena, userTeam:Team) extends JPanel {
  private val SPRITE_SIDE = 72

  private val terrainImage = new ImageInfo(miniArena.terrain.path, "").buildImage
  private var _host:Option[PlayerSprite] = None
  private var _guest:Option[PlayerSprite] = None

  def host = miniArena.host
  def guest = miniArena.guest
  def battle = miniArena.battle

  refresh()

  override def paintComponent(g:Graphics) {
    super.paintComponent(g)
    val graphics = g.asInstanceOf[Graphics2D]

    // render two images one above another in the center of the component
    terrainImage.render(graphics, firstTerrainPos)
    terrainImage.render(graphics, secondTerrainPos)
    _guest.foreach(_.coordinates = guestPos)
    _host.foreach(_.coordinates = hostPos)

    if (_guest.map(_.state.isAttack).getOrElse(false)) {
      _guest.foreach(_.render(graphics))
      _host.foreach(_.render(graphics))
    } else {
      _host.foreach(_.render(graphics))
      _guest.foreach(_.render(graphics))
    }
  }

  private def firstTerrainPos:Point = {
    new Point((dim.width - terrainImage.width) / 2,
      dim.height / 2)
  }

  private def secondTerrainPos:Point = {
    new Point((dim.width - terrainImage.width) / 2,
      (dim.height - terrainImage.height * 2) / 2)
  }

  private def dim = getSize:Dimension

  private def hostPos = {
    if (hostIsUser) {
      firstTerrainPos
    } else {
      secondTerrainPos
    }
  }

  private def guestPos = {
    if (hostIsUser) {
      secondTerrainPos
    } else {
      firstTerrainPos
    }
  }


  private def hostIsUser = battle.hostTeam == userTeam

  def refresh() {
    _host = miniArena.host.map(loadPlayerSprite(true, _))
    _guest = miniArena.guest.map(loadPlayerSprite(false, _))

    repaint()
  }

  def playerSpriteView(state:PlayerState):Option[PlayerSprite] = {
    List(_host, _guest).flatten.find(_.playerState == state)
  }

  private def loadPlayerSprite(host:Boolean, state:PlayerState):PlayerSprite = {
    val info = PlayerTypeInfoLoader.types(state.playerType.name).view.spriteForLevel(state.player.level)
    new PlayerSprite(state, info, host, SpriteSoundConfigurationLoader.configurations(info.spriteSoundConfigName),
      info.attackEffect)
  }

}
